﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Threading.Tasks;
using System.Reflection;

namespace Mengsk.ERP.Orders.TDOrderInterfaces
{
    public abstract class TDOrderInterfaceBase
    {
        private static TDOrderInterfaceBase[] orderInterfaces = null;

        public static TDOrderInterfaceBase[] AllOrderInterfaces
        {
            get
            {
                if (orderInterfaces == null)
                {
                    orderInterfaces = LoadOrderManagers();
                }
                return orderInterfaces;
            }
        }

        protected bool isStop = false;
        private Task downloadTask = null;
        private object taskLock = new object();

        public abstract Shop Shop { get; }

        public abstract bool AcceptOrder(string popId);

        public event EventHandler OrderDownloadStart;

        public event EventHandler<OrderDownloadEventArgs> OrderDownloading;

        public event EventHandler<DownloadEndEventArgs> OrderDownloadEnd;

        /// <summary>
        /// 下载订单数据,不包括图片和详情
        /// </summary>
        /// <param name="popId"></param>
        /// <param name="createTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        public static Order GetOrder(string popId, DateTime createTime, DateTime endTime)
        {
            var td = AllOrderInterfaces.FirstOrDefault(obj => obj.AcceptOrder(popId));
            if (td == null)
            {
                throw new Exception("不支付的订单");
            }

            OrderDownloadArgs args = new OrderDownloadArgs
            {
                DownLoadItems = false,
                DwonloadItemsImage = false,
                StartTime = createTime,
                EndTime = endTime,
                OrderState = "",
                RaiseEvents = false,
                Id = popId,

            };

            Order[] items = td.DownloadOrders(args);
            if (items == null || items.Length < 1)
            {
                return null;
            }
            return items[0];
        }

        protected virtual void OnOrderDownloadStart()
        {
            if (this.OrderDownloadStart != null)
            {
                this.OrderDownloadStart(this, new EventArgs());
            }
        }

        protected virtual void OnOrderDownloading(OrderDownloadEventArgs e)
        {
            if (this.OrderDownloading != null)
            {
                this.OrderDownloading(this, e);
            }
        }

        protected bool AcceptOrder(object creator)
        {
            if (creator == null || creator.GetType() != typeof(Shop))
            {
                return false;
            }

            return this.Shop == (Shop)creator;
        }

        protected virtual void OnOrderDownloadEnd(Exception exception)
        {
            if (this.OrderDownloadEnd != null)
            {
                this.OrderDownloadEnd(this, new DownloadEndEventArgs(exception));
            }
        }

        protected void DownloadOrdersTask(OrderDownloadArgs args)
        {
            Exception e = null;
            try
            {
                this.OnOrderDownloadStart();
                this.DownloadOrders(args);
            }
            catch (Exception ex)
            {
                e = ex;
            }
            finally
            {
                lock (this.taskLock)
                {
                    this.isStop = false;
                    this.downloadTask = null;
                }
                this.OnOrderDownloadEnd(e);
            }
        }

        public void StartDownloadOrders(OrderDownloadArgs args)
        {
            lock (this.taskLock)
            {
                if (this.downloadTask != null)
                {
                    throw new InvalidProgramException("已启动下载,无法再次启动");
                }
                this.isStop = false;
                this.downloadTask = Task.Factory.StartNew(() => this.DownloadOrdersTask(args));
            }
        }

        public void StopDownloadOrders()
        {
            Task tmp = null;
            lock (this.taskLock)
            {
                if (this.downloadTask == null)
                {
                    throw new InvalidProgramException("未启动下载，无法停止");
                }
                tmp = this.downloadTask;
                this.isStop = true;
            }
        }

        public abstract Order[] DownloadOrders(OrderDownloadArgs args);

        public abstract Order DownLoadOrder(string orderID, DateTime orderCreateTime, bool downloadItemImage);

        public abstract void Initialize(XElement xelement, string shop);

        public abstract void UpdateOrderComment(string orderID, OrderFlag flag, string sellerComment);

        public abstract void CloseOrder(string orderID);

        public abstract void UpdateOrderAddress(string orderID, string name, string address);

        public abstract void GetDeliveryInfo(string dealId, ref string deliveryCompany, ref string deliveryNumber);

        public abstract string GetDeliveryTrack(string dealId, string deliveryCompany, string deliveryNumber);

        public static TDOrderInterfaceBase[] LoadOrderManagers()
        {
            XDocument xDoc = XDocument.Parse(Properties.Resource.Shops);
            List<TDOrderInterfaceBase> orderManagers = new List<TDOrderInterfaceBase>();

            foreach (XElement xe in xDoc.Root.Elements("Shop"))
            {
                string strName = xe.Attribute("Name").Value;
                string strAssembly = xe.Attribute("Assembly").Value;
                string strClass = xe.Attribute("Class").Value;

                if (string.IsNullOrWhiteSpace(strName) ||
                    string.IsNullOrWhiteSpace(strClass))
                {
                    continue;
                }

                Assembly assembly = null;

                if (string.IsNullOrWhiteSpace(strAssembly) == false)
                {
                    assembly = Assembly.Load(strAssembly);
                }
                else
                {
                    assembly = typeof(TDOrderInterfaceBase).Assembly;
                }
                Type type = assembly.GetType(strClass);

                TDOrderInterfaceBase orderManager = Activator.CreateInstance(type) as TDOrderInterfaceBase;

                orderManager.Initialize(xe.Elements("Security").First(), strName);

                orderManagers.Add(orderManager);
            }

            orderInterfaces = orderManagers.ToArray();
            return orderInterfaces;
        }

        public static TDOrderInterfaceBase GetOrderInterfaceSource(object creator)
        {
            return orderInterfaces.FirstOrDefault((obj => obj.AcceptOrder(creator)));
        }
    }
}
